/*
 * Copyright (c) 2015. For Intelligent Group.
 */

package com.intelligent.ispc.core.service.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.intelligent.ispc.common.utils.ApplicationUtil;
import com.intelligent.ispc.common.utils.FileUtils;
import com.intelligent.ispc.core.dto.*;
import com.intelligent.ispc.core.service.ExportFileService;
import com.intelligent.ispc.core.service.GRRExportService;
import com.intelligent.ispc.core.service.GRRTestDataService;
import com.intelligent.ispc.core.service.ProjectService;
import com.intelligent.ispc.export.grr.GrrExportCellFactory;
import com.intelligent.ispc.export.grr.GrrExcelBuilder;
import com.intelligent.ispc.external.rcall.service.AnalysisService;
import com.intelligent.ispc.utils.Constant;
import com.intelligent.ispc.utils.DataSourceType;
import com.intelligent.ispc.utils.ExportFileStatus;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * Created by cherry on 2016/6/8.
 */
@Service
public class GRRExportServiceImpl implements GRRExportService {

    private static Logger logger = LoggerFactory.getLogger(GRRExportServiceImpl.class);

    @Autowired
    private TaskExecutor taskExecutor;

    @Autowired
    private AnalysisService analysisService;

    @Autowired
    private SimpMessagingTemplate msgTemplate;

    @Autowired
    private GRRTestDataService grrTestDataService;

    @Autowired
    private ProjectService projectService;

    @Autowired
    private ExportFileService exportFileService;

    @Override
    public void exportResultToExcel(Map<String, Object> searchParams) {
        Subject subject = SecurityUtils.getSubject();
        SecurityUserDto dto = (SecurityUserDto) subject.getPrincipal();
        String loginName = dto.getLoginName();
        Long userId = dto.getId();
        searchParams.put(Constant.GLOBAL_LOGIN_NAME, loginName);
        searchParams.put(Constant.GLOBAL_USER_ID, userId);
        taskExecutor.execute(new Thread() {
            public void run() {

                Map<String, Object> exportParams = Maps.newHashMap();
                String grrName = (String) searchParams.get("grrName");
                DateTimeFormatter format = DateTimeFormat.forPattern("yyyyMMddHHmmss");
                DateTime now = new DateTime();
                String fix = now.toString(format);
                String fileType = (String) searchParams.get("fileType");
                String projectName = (String) searchParams.get("projectName");
                String projectId = (String) searchParams.get("projectId");
                exportParams.put("grrName", grrName);

                StringBuilder sb = new StringBuilder();
                sb.append("export_").append(projectName).append("_").append("GRR").append("_").append(fix)
                        .append(".").append(fileType);
                String fileName = sb.toString();
                String savePath = ApplicationUtil.getProjectPathWithSeparator() + "exports" + ApplicationUtil.getFileSeparator();

                String filePath = savePath + fileName;
                ExportFileDto exportFileDto = new ExportFileDto();
                exportFileDto.setCreateBy(loginName);
                exportFileDto.setCreateTime(now.toDate());
                exportFileDto.setProjectName(projectName);
                exportFileDto.setStatus(ExportFileStatus.EXPORTING.toString());
                exportFileDto.setUrl("exportsfile/" + fileName);
                exportFileDto.setDataType(DataSourceType.GRR.getCode());
                Long fileId = exportFileService.createExportFile(exportFileDto);
                logger.debug("Export grr only result to file:{}", fileName);

                try {
                    List<GRRSummaryDto> grrSummaryDtoList = grrTestDataService.searchGRRSummaryForExport(searchParams);
                    List<GRRTestDataDto> grrTestDataDtoList = grrTestDataService.searchGRRTestDatas(searchParams);
                    List<PSAttributeDto> psAttributeDtoList = projectService.findPSAttributeByProject(projectId);
                    exportParams.put(Constant.GRR_RULE_VALUE, searchParams.get(Constant.GRR_RULE_VALUE));
                    GrrExportCellFactory factory = new GrrExportCellFactory();
                    factory.buildGRRBySlot(exportParams, grrSummaryDtoList, null, grrTestDataDtoList, psAttributeDtoList);
//
                    GrrExcelBuilder grrExcelBuilder = new GrrExcelBuilder(null,null);
                    grrExcelBuilder.drawExcel(filePath, factory);

                    exportFileService.updateExportFileStatus(fileId, ExportFileStatus.FINISHED);

                    msgTemplate.setUserDestinationPrefix("/data/");
                    msgTemplate.convertAndSend("/topic/data/exportDownloadListener#" + userId, "{'result':'success','url':'"+ exportFileDto.getUrl() +"'}");

                }catch (Exception e) {
                    logger.error("export grr only result failed!", e);
                    logger.error("export grr only result failed!", e);
                    exportFileService.updateExportFileStatus(fileId, ExportFileStatus.FAILED);
                    msgTemplate.setUserDestinationPrefix("/data/");
                    msgTemplate.convertAndSend("/topic/data/exportDownloadListener#" + userId, "{'result':'error','url':'"+ exportFileDto.getUrl() +"'}");
                }
            }
        });
    }

    @Override
    public void exportResultAndDataToExcel(Map<String, Object> searchParams) {
        Subject subject = SecurityUtils.getSubject();
        SecurityUserDto dto = (SecurityUserDto) subject.getPrincipal();
        String loginName = dto.getLoginName();
        Long userId = dto.getId();
        searchParams.put(Constant.GLOBAL_LOGIN_NAME, loginName);
        searchParams.put(Constant.GLOBAL_USER_ID, userId);
        taskExecutor.execute(new Thread() {
            public void run() {

                Map<String, Object> exportParams = Maps.newHashMap();
                String grrName = (String) searchParams.get("grrName");
                DateTimeFormatter format = DateTimeFormat.forPattern("yyyyMMddHHmmss");

                DateTime now = new DateTime();
                String fix = now.toString(format);
                String fileType = (String) searchParams.get("fileType");
                String projectName = (String) searchParams.get("projectName");
                String projectId = (String) searchParams.get("projectId");
                exportParams.put("grrName", grrName);

                StringBuilder sb = new StringBuilder();
                sb.append("export_").append(projectName).append("-").append("GRR").append("_")
                        .append("_").append(fix).append(".").append(fileType);
                String fileName = sb.toString();
                String savePath = ApplicationUtil.getProjectPathWithSeparator() + "exports" + ApplicationUtil.getFileSeparator();
                String filePath = savePath + fileName;

                ExportFileDto exportFileDto = new ExportFileDto();
                exportFileDto.setCreateBy(loginName);
                exportFileDto.setCreateTime(now.toDate());
                exportFileDto.setProjectName(projectName);
                exportFileDto.setStatus(ExportFileStatus.EXPORTING.toString());
                exportFileDto.setDataType(DataSourceType.GRR.getCode());
                exportFileDto.setUrl("exportsfile/" + fileName);
                Long fileId = exportFileService.createExportFile(exportFileDto);

                logger.debug("Export grr only result to file:{}", fileName);
                try {
                    List<GRRExportResultDto> grrExportResultDtoList = grrTestDataService.searchGRRExportResult(searchParams);
                    List<GRRTestDataDto> grrTestDataDtoList = grrTestDataService.searchGRRTestDatas(searchParams);
                    List<PSAttributeDto> psAttributeDtoList = projectService.findPSAttributeByProject(projectId);
                    List<GRRSummaryDto> grrSummaryDtoList = Lists.newArrayList();
                    if (!grrExportResultDtoList.isEmpty()) {
                        grrSummaryDtoList = grrExportResultDtoList.get(0).getGrrSummaryDtoList();
                    }

                    double operator = (Double) searchParams.get(Constant.GRR_OPERATOR_VALUE);
                    double trial = (Double) searchParams.get(Constant.GRR_TRIAL_VALUE);
                    double parts = (Double) searchParams.get(Constant.GRR_PART_VALUE);
                    double sigma = (Double) searchParams.get(Constant.GRR_SIGMA_VALUE);
                    String rules = (String) searchParams.get(Constant.GRR_RULE_VALUE);
                    String model = (String) searchParams.get(Constant.GRR_MODEL_VALUE);

                    for (int i=0; i<grrExportResultDtoList.size(); i++) {

                        List<String> imagePaths = grrExportResultDtoList.get(i).getImgPaths();
                        String [] imagePathArray = imagePaths.toArray(new String[imagePaths.size()]);
                        String usl = grrExportResultDtoList.get(i).getGrrExportParamDto().getUsl();
                        String lsl = grrExportResultDtoList.get(i).getGrrExportParamDto().getLsl();
                        String itemName = grrExportResultDtoList.get(i).getGrrExportParamDto().getTestItemName();
                        searchParams.put("itemName", itemName);
                        GRRAnalysisParamDto grrAnalysisParamDto = grrTestDataService.searchGRRTestItem(searchParams);
                        grrAnalysisParamDto.setUsl(Double.valueOf(usl));
                        grrAnalysisParamDto.setLsl(Double.valueOf(lsl));

                        Map<String, Object> param = Maps.newHashMap();
                        param.put(Constant.GRR_OPERATOR_VALUE, operator);
                        param.put(Constant.GRR_PART_VALUE, parts);
                        param.put(Constant.GRR_TRIAL_VALUE, trial);
                        param.put(Constant.GRR_SIGMA_VALUE, sigma);
                        param.put(Constant.GRR_CHARTS_PATH, imagePathArray);

                        analysisService.analyseGRRChartPlot(param, grrAnalysisParamDto);
                    }

                    exportParams.put(Constant.GRR_SIGMA_VALUE, sigma);
                    exportParams.put(Constant.GRR_RULE_VALUE, rules);
                    exportParams.put(Constant.GRR_MODEL_VALUE, model);

                    GrrExportCellFactory factory = new GrrExportCellFactory();
                    factory.buildGRRBySlot(exportParams, grrSummaryDtoList, grrExportResultDtoList, grrTestDataDtoList, psAttributeDtoList);

//                    String filePath1 = "k:/test1.xls";
                    GrrExcelBuilder grrExcelBuilder = new GrrExcelBuilder( (int)operator, (int)trial);
                    grrExcelBuilder.drawExcel(filePath, factory);

                    //delete pictures
                    for(int i=0; i<grrExportResultDtoList.size(); i++) {
                        FileUtils.deleteFile(grrExportResultDtoList.get(i).getImgPaths().toArray().toString());
                    }
                    exportFileService.updateExportFileStatus(fileId, ExportFileStatus.FINISHED);
                    msgTemplate.setUserDestinationPrefix("/data/");
                    msgTemplate.convertAndSend("/topic/data/exportDownloadListener#" + userId, "{'result':'success','url':'"+ exportFileDto.getUrl() +"'}");

                } catch (Exception e) {
                    logger.error("export grr only result failed!", e);
                    exportFileService.updateExportFileStatus(fileId, ExportFileStatus.FAILED);
                    msgTemplate.setUserDestinationPrefix("/data/");
                    msgTemplate.convertAndSend("/topic/data/exportDownloadListener#" + userId, "{'result':'error','url':'"+ exportFileDto.getUrl() +"'}");
                }

            }
        });
    }
}
